#ifndef POINT_H_
#define POINT_H_
#include <iostream>

template<typename T> class Point {
	template<typename V> friend std::ostream& operator<<(std::ostream&, Point<V>&);
public:
	Point(T, T);
	virtual ~Point();

	Point<T>& operator+(const Point<T>&) const;
	bool operator==(const Point<T>&) const;
	bool operator!=(const Point<T>&) const;

	T getX() const;
	void setX(T x);

	T getY() const;
	void setY(T y);

private:
	T x;
	T y;
};

template<typename T> Point<T>::Point(T _x = 0, T _y = 0) : x(_x), y(_y) { }

template<typename T> Point<T>::~Point() { }

template<typename T> Point<T>& Point<T>::operator+(const Point<T>& snd) const {
	Point<T> *ris = new Point<T>(x + snd.x, y + snd.y);
	return *ris;
}

template<typename T> bool Point<T>::operator==(const Point<T>& snd) const {
	return (snd.x == x) && (snd.y == y);
}

template<typename T> bool Point<T>::operator!=(const Point<T>& snd) const {
	return (snd.x != x) && (snd.y != y);
}

template<typename T> T Point<T>::getX() const {
	return x;
}

template<typename T> T Point<T>::getY() const {
	return y;
}

template<typename T> void Point<T>::setX(T _x) {
	x = _x;
}

template<typename T> void Point<T>::setY(T _y) {
	y = _y;
}

template<typename V> std::ostream& operator<<(std::ostream& os, Point<V>& pt) {
	os << pt.x << " " << pt.y;
	return os;
}

#endif
